package com.winhxd.b2c.common.config;

import com.winhxd.b2c.common.context.CustomerUser;
import com.winhxd.b2c.common.context.UserContext;
import com.winhxd.b2c.common.domain.common.ApiCondition;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * ControllerParamFillConfig
 *
 * @Author 李中华
 * @Date 2019/1/12 15:49
 * @Description:
 */
@Aspect
@Component
public class ControllerParamFillConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(ControllerParamFillConfig.class);
    //前缀
    private static final String LOGGER_PREFIXES = "[API接口填充用户ID]";
    //分隔符
    private static final String SEPARATOR = " ";

    private static final String START = "Api";

    @Pointcut(value = "@within(org.springframework.web.bind.annotation.RestController)")
    private void restControllerMethod() {
    }

    @Pointcut(value = "@within(org.springframework.stereotype.Controller)")
    private void controllerMethod() {
    }

    /**
     * 切点前置增强
     */
    @Before(value = "restControllerMethod() || controllerMethod()")
    public void fillCustomerId(JoinPoint joinPoint) {
        CustomerUser customerUser = UserContext.getCurrentCustomerUser();
        if (customerUser == null) {
            return;
        }

        //验证方法访问控制符
        if ((joinPoint.getSignature().getModifiers() & 1) != 1) {
            LOGGER.error(LOGGER_PREFIXES + getMethodName(joinPoint) + "method modifiers error.");
            return;
        }
        //验证是否为apicontroller接口，使用方法为验证api开头
        String[] className = joinPoint.getSignature().getDeclaringTypeName().split("\\.");
        boolean startsWith = className[className.length - 1].startsWith(START);
        if (!startsWith) {
            return;
        }

        //获取连接点方法运行时的入参列表
        Object[] pointArgs = joinPoint.getArgs();
        if (pointArgs == null || pointArgs.length == 0) {
            return;
        }
        // 遍历参数, 设置ApiCondition的customerId
        for (Object object : pointArgs) {
            //判断是否为ApiCondition或者其子类
            if (!ApiCondition.class.isAssignableFrom(object.getClass())) {
                continue;
            }
            ApiCondition condition = (ApiCondition) object;
            condition.setCustomerId(customerUser.getCustomerId());
        }
    }


    private String getMethodName(JoinPoint joinPoint) {
        return SEPARATOR + joinPoint.getSignature().toString().split(SEPARATOR)[1] + SEPARATOR;
    }
}
